#include "sphere.h"

bool sphere::hit(const ray &r, interval ray_t, hit_record &rec) const
{
    vec3 oc = center - r.origin();
    auto a = r.direction().length_squared();
    auto h = dot(r.direction(), oc);
    auto c = oc.length_squared() - radius * radius;
    auto discriminant = h * h - a * c;
    if (discriminant < 0)
        return false;

    auto sqrtd = std::sqrt(discriminant);
    auto root = (h - sqrtd) / a;
    //找最先碰到球体的根,可能只有1根,为sqrtd为的时候也包含在内，至多判断2次，返回结果
    if(!ray_t.surrounds(root)) {
        root = (h + sqrtd) / a;
        if (!ray_t.surrounds(root))
            return false;
    }

    if(sqrtd < 0.2) {//超级粗可视
        //如果是轮廓线
        rec.is_contour = true;
    } else {
        rec.is_contour = false;
    }
    rec.t = root;
    //交点坐标
    rec.p = r.at(rec.t);
    //交点处单位法向量
    vec3 outward_normal = (rec.p - center) / radius;
    //判断法向量的方向朝外还是朝内
    rec.set_face_normal(r, outward_normal);
    return true;
}